#!/bin/bash

#####################################################
# description: install pcloudanget for linux（bash) host
# function:
#    1. install_pcloudagent(){
#        1. download binary file (pcloudagent)
#        2. download config file (/conf/config.toml)
#        3. download config file (/conf/input*)
#    }
#    2. start_pcloudagent(){
#        1. start pcloudagent in daemon mode
#    }

# usage: bash ${0} -b /opt/cde -u http://127.0.0.1:8000
# mongo: curl -sfL http://1.14.137.155:17000/api/pcloud/download/install_pcloudagent.sh |bash -s -- -d mongo -i 123456 -o true
# redis: curl -sfL http://1.14.137.155:17000/api/pcloud/download/install_pcloudagent.sh |bash -s -- -d redis -o true -i 123456 -I "175.178.65.213" 
#    args:
#       -b  Specify the installation path
#       -u  Specify the URL of the file download [http://1.14.137.155:17000]
#       -d  Specify databaseType parameter of the URL [mongo|redis|mysql|redis_sentinel]
#       -i  Specify id parameter  of the URL [1234567xyzs]
#       -o  Specify overAll parameter  of the URL [true|false]
#       -I  Specify redisIp parameter  of the URL ["175.178.65.213"]
#
#####################################################

# logfile=/tmp/${0}.$(date "+%F-%H:%M:%S").log
# echo "you can use: \`tail -f ${logfile}\` to view install log "
# exec >${logfile} 2>&1

# defalut variables
# url="http://1.14.137.155:17000"
baseDir="/opt/pcloudagent"
# mongo & redis & mysql
overAll=true
# databaseType=redis

# mongo & mysql
hostName=$(hostname)


install_pcloudagent(){
    # 0. prefix
    check(){
        # set -x
    if [ `stat -c %s ${baseDir}/$1` -gt 0 ]; then
                echo "$(date "+%F %H:%M:%S")I! download  file to the ${baseDir}/$1 successful."
    else
            echo "$(date "+%F %H:%M:%S")E! The downloaded file[$1] is empty or has an unexpected size."
            exit 1
        fi
    # set +x

    }
    
    # add input redisIp for redis 
    # 2024/03/28 by wangendao
    input_ip() {
        regex='^([0-9]{1,3}\.){3}[0-9]{1,3}$'
        i=0
        while [ $i -lt 3 ]; do
            read -p "You must input your IP of Redis instance bind: " -t 180 redisIp
            if [[ $redisIp =~ $regex ]]; then
                # IP 格式正确，进行进一步的范围检查
                octets=$(echo $redisIp | tr '.' ' ')
                for octet in $octets; do
                    if ! [[ $octet -le 255 && $octet -ge 1 ]]; then
                        echo "$redisIp is not a valid IP address."
                        exit 1
                    fi
                done
                # 如果 IP 地址有效，跳出函数，继续执行脚本的其他部分
                return
            else
                echo "Invalid input or timeout. Please try again."
            fi
            i=$((i+1))
        done
        # 如果三次尝试后仍未输入有效的 IP 地址，退出脚本
        echo "Failed to input a valid IP address after 3 attempts."
        exit 1
    }
    
    # 2024/04/10 by wangendao
    modfify_logfile(){
        logpaht=$(awk -F '"'  '/log_file_path/{print $2}' /opt/pcloudagent/conf/input.promtail/promtail.toml)

        for file in ${logpaht}*.log; do
            echo -e "create by pcloud agent \n" >> "$file"
        done
    }


    get_toml(){
                # download config file 
                _dir=$(dirname $1)
                _name=$(basename $1)

                if [ -e "${baseDir}/$1" ] ;then
                    echo $(date "+%F %H:%M:%S")I! backup $1 to /tmp/${_name}.$(date "+%F-%H:%M:%S")
                    mv ${baseDir}/$1 /tmp/${_name}.$(date "+%F-%H:%M:%S")
                else
                    mkdir -p ${baseDir}/${_dir}
                fi
                echo "$(date "+%F %H:%M:%S")I! download config file $1 from from $2"
                curl -s --location --request GET $2 -o ${baseDir}/$1
                if [ $? -eq 0 ] ;then
                    check $1 
                else
                    echo "$(date "+%F %H:%M:%S")E! request $2 timeout,please check network or ${url} services !!!" 
                    exit 1
                fi
    }

    add_hosts(){

            # $1=${url}/api/pcloud/nanotube/mongo/getHost?id=${id}
            readarray -t  str < <(curl -s $1|awk -F '"' '{print $6}'|awk -F ',' '{for(i=1;i<=NF;i++){print $i}}')
            echo "$(date "+%F %H:%M:%S")I! get ${str[@]} from $1"

            i=0
            while [ $i -lt ${#str[@]} ];do
                grep -q "${str[$i]}" /etc/hosts 
                
                if [ $? -eq 0 ];then
                    echo "$(date "+%F %H:%M:%S")I! ${str[$i]} already in /etc/hosts, pass."
                else
                    echo "$(date "+%F %H:%M:%S")I!  ${str[$i]} will append to /etc/hosts."
                    sudo echo ${str[$i]} >>/etc/hosts
                    grep -q "${str[$i]}" /etc/hosts || echo "$(date "+%F %H:%M:%S")E! add ${str[$i]}to /etc/hosts failed!!!"
                fi

                i=$(($i+1))
            done
    }
    # 2. download config file (/conf/*) 

    case ${databaseType} in
        mongo)
            # download config file (/conf/config.toml)
            get_toml "conf/config.toml"  "${url}/api/pcloud/nanotube/mongo/getConfig?appKey=${appKey}&id=${id}&hostname=${hostName}&overAll=${overAll}"

            # download config file (/conf/input.*)
            get_toml "conf/input.mongodb/mongodb.toml "  "${url}/api/pcloud/nanotube/mongo/getMongo?appKey=${appKey}&id=${id}&overAll=${overAll}&hostname=${hostName}"

            # download config file (conf/input.promtail/promtail.toml)
            [ $overAll == "true" ] && get_toml "conf/input.promtail/promtail.toml"  "${url}/api/pcloud/nanotube/mongo/getPromTail?appKey=${appKey}&id=${id}&overAll=${overAll}&hostname=${hostName}"

            # 判断是否在 /etc/hosts 中存在映射
            # curl -s http://1.14.137.155:17000/api/pcloud/nanotube/mongo/getHost?id=661de231cd998455531a2773|awk -F '"' '{print $6}'
            add_hosts ${url}/api/pcloud/nanotube/mongo/getHost?appKey=${appKey}&id=${id}

            ;;
        redis)
            # input ip 
            [ $overAll == "true" ] && input_ip

            # download config file (/conf/config.toml)
            get_toml "conf/config.toml"  "${url}/api/pcloud/nanotube/redis/getConfig?appKey=${appKey}&id=${id}&overAll=${overAll}"

            # download config file (/conf/input.*)
            if [ $overAll == "true" ];then
                get_toml "conf/input.redis/redis.toml"  "${url}/api/pcloud/nanotube/redis/getNodeConfig?appKey=${appKey}&id=${id}&overAll=${overAll}&ip=${redisIp}"
            else
                get_toml "conf/input.redis/redis.toml"  "${url}/api/pcloud/nanotube/redis/getNodeConfig?appKey=${appKey}&id=${id}&overAll=${overAll}"
            fi


            # download config file (conf/input.promtail/promtail.toml)
            if [ $overAll == "true" ] ;then
                get_toml "conf/input.promtail/promtail.toml"  "${url}/api/pcloud/nanotube/redis/getNodeLokiConfig?appKey=${appKey}&id=${id}&overAll=${overAll}&ip=${redisIp}"
                modfify_logfile
            fi

            ;;
        mysql)
            # download config file (/conf/config.toml)
            get_toml "conf/config.toml"  "${url}/api/pcloud/nanotube/mysql/getConfig?appKey=${appKey}&id=${id}&overAll=${overAll}"

            # download config file (/conf/input.*)
            get_toml "conf/input.mysql/mysql.toml" "${url}/api/pcloud/nanotube/mysql/getMysqlToml?appKey=${appKey}&id=${id}&overAll=${overAll}&hostname=${hostName}"

            # download config file (conf/input.promtail/promtail.toml)
            [ $overAll == "true" ] && get_toml "conf/input.promtail/promtail.toml" "${url}/api/pcloud/nanotube/mysql/getPromTail?appKey=${appKey}&id=${id}&overAll=${overAll}&hostname=${hostName}"
            add_hosts ${url}/api/pcloud/nanotube/mysql/getHost?appKey=${appKey}&id=${id}
            
            ;;
        redis_sentinel)
            # input ip 
            [ $overAll == "true" ] && input_ip

            # download config file (/conf/config.toml)
            get_toml "conf/config.toml"  "${url}/api/pcloud/nanotube/redis/getConfig?appKey=${appKey}&id=${id}&overAll=${overAll}"

            # download config file (/conf/input.*)
            if [ $overAll == "true" ];then
                get_toml "conf/input.redis/redis.toml"  "${url}/api/pcloud/nanotube/redis/getNodeConfig?appKey=${appKey}&id=${id}&overAll=${overAll}&ip=${redisIp}"
            else
                get_toml "conf/input.redis/redis.toml"  "${url}/api/pcloud/nanotube/redis/getNodeConfig?appKey=${appKey}&id=${id}&overAll=${overAll}"
            fi

            
            # download config file (conf/input.promtail/promtail.toml)
            if [ $overAll == "true" ] ;then
                get_toml "conf/input.promtail/promtail.toml"  "${url}/api/pcloud/nanotube/redis/getNodeLokiConfig?appKey=${appKey}&id=${id}&overAll=${overAll}&ip=${redisIp}"
                modfify_logfile
            fi
            
            # download config file (conf/input.redis_sentinel/redis_sentinel.toml)
            if [ $overAll == "true" ];then
                get_toml "conf/input.redis_sentinel/redis_sentinel.toml"  "${url}/api/pcloud/nanotube/redis/getSentinelNodeConfig?appKey=${appKey}&id=${id}&overAll=${overAll}&ip=${redisIp}"
            else
                get_toml "conf/input.redis_sentinel/redis_sentinel.toml"  "${url}/api/pcloud/nanotube/redis/getSentinelNodeConfig?appKey=${appKey}&id=${id}&overAll=${overAll}"
            fi
            ;;
    esac

    # 1. download binary file (pcloudagent)
    echo "$(date "+%F %H:%M:%S")I! download binary file (pcloudagent) from ${url}/api/pcloud/download/pcloudagent.tar.gz "
    # wget --timeout=900 --tries=3  https://pcloudagent.oss-cn-shenzhen.aliyuncs.com/pcloudagent.tar.gz -O ${baseDir}/pcloudagent.tar.gz
    curl -# --max-time 900 --retry 3 --retry-delay 5 -X GET "https://pcloudagent.oss-cn-shenzhen.aliyuncs.com/pcloudagent.tar.gz" -o ${baseDir}/pcloudagent.tar.gz
    if [ $? -eq 0 ];then
        check pcloudagent.tar.gz
        if [ $? -eq 0 ];then
            tar xf ${baseDir}/pcloudagent.tar.gz  -C ${baseDir} && chmod +x ${baseDir}/pcloudagent
            rm -fr ${baseDir}/pcloudagent.tar.gz
        fi
    fi
}


start_pcloudagent() {

    # Stop the old process
    ps -ef|grep pcloudagent |grep -v grep &>/dev/null && pkill pcloudagent
    rm -fr /etc/systemd/system/pcloudagent.service

    # Run the installation script "pcloudagent.service"
        echo "$(date "+%F %H:%M:%S")I! Configure the startup command pcloudagent.service..."
        ${baseDir}/pcloudagent -install 2>/dev/null
        sed  -i  '/\[Install\]/iLimitNOFILE=100000\nLimitNPROC=65535' /etc/systemd/system/pcloudagent.service && \
        systemctl daemon-reload && systemctl restart pcloudagent


    # 
        retry=0
        ensurestarted() {
                status=$(systemctl is-active pcloudagent.service)
                if [ "$status" == "active" ]; then
                        echo "$(date "+%F %H:%M:%S")I! pcloudagent service started sucessfully !!!"
                        exit
                else
                        systemctl restart pcloudagent
                        retry=$(($retry+1))
                        echo "$(date "+%F %H:%M:%S")I! Wait the pcloudagent service to start. loop【$retry】..."
                        sleep 3

                fi
        }

        for i in $(seq 5); do
             ensurestarted
        done
}



while getopts ":b:u:i:o:I:d:k:" opt; do
    case $opt in
        b)
            baseDir=$OPTARG
            ;;
        u)
            url=$OPTARG
            ;;
        i)
            id=$OPTARG
            ;;
        o)
            overAll=$OPTARG
            ;;
        I)
            redisIp=$OPTARG
            ;;
        d)
            databaseType=$OPTARG
            ;; 
        k)
            appKey=$OPTARG
            ;; 
        *)
            echo "$(date "+%F %H:%M:%S")I! Invalid option: -$OPTARG" >&2
            exit 1
            ;;
    esac
done

# Create necessary directories
if [ ! -d "${baseDir}/conf" ] ;then
    mkdir -p ${baseDir}/conf
else
    if [ -e "${baseDir}/pcloudagent" ];then

        echo "$(date "+%F %H:%M:%S")I! backup ${baseDir}/pcloudagent  to /tmp/pcloudagent.$(date "+%F-%H:%M:%S")"
        mv ${baseDir}/pcloudagent /tmp/pcloudagent.$(date "+%F-%H:%M:%S")
    fi
    if [ -e "${baseDir}/conf/config.toml" ];then
        echo "$(date "+%F %H:%M:%S")I! backup ${baseDir}/conf/config.toml to /tmp/config.toml.$(date "+%F-%H:%M:%S")"
        mv ${baseDir}/conf/config.toml /tmp/config.toml.$(date "+%F-%H:%M:%S")
    fi
fi

# exec 
if [ $# -gt 2 ];then
    install_pcloudagent
    start_pcloudagent
else
cat << EOF
$(date "+%F %H:%M:%S")E! You must input right argument.
    args:
        -b  Specify the installation path
        -u  Specify the URL of the file download [http://1.14.137.155:17000]
        -d  Specify databaseType parameter of the URL [mongo|redis|mysql|redis_sentinel]
        -i  Specify id parameter  of the URL [1234567xyzs]
        -o  Specify overAll parameter  of the URL [true|false]
        -I  Specify redisIp parameter  of the URL ["175.178.65.213"]
EOF
fi